﻿using System.Threading;
using System.Collections;

namespace Blackhole.Logger
{
    public abstract class LoggerBase
    {
        private bool isRunning;

        private Queue messageQueue;
        private Thread dispatcherThread;

        public LoggerBase()
        {
            this.messageQueue = Queue.Synchronized(new Queue());

            this.isRunning = false;

            this.Start();
        }

        public abstract void LogMessage(LogArguements arguements);

        public void Log(LogArguements arguements)
        {
            Monitor.Enter(this.messageQueue);

            this.messageQueue.Enqueue(arguements);

            Monitor.PulseAll(this.messageQueue);

            Monitor.Exit(this.messageQueue);
        }

        private void DispatcherThreadFunc()
        {
            while (this.isRunning)
            {
                Monitor.Enter(this.messageQueue);

                if (this.messageQueue.Count != 0)
                {
                    this.LogMessage((LogArguements)this.messageQueue.Dequeue());
                }

                Monitor.PulseAll(this.messageQueue);

                Monitor.Exit(this.messageQueue);
            }
        }

        public void Start()
        {
            this.isRunning = true;

            this.dispatcherThread = new Thread(new ThreadStart(this.DispatcherThreadFunc));

            this.dispatcherThread.Start();
        }

        public void Stop()
        {
            this.isRunning = false;
        }
    }
}